﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;

namespace BaseMod4
{
    public class Lineint2
    {
        private const double epsilon = 1e-10;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="a1">线1上的一点</param>
        /// <param name="v1">线1的方向向量</param>
        /// <param name="a2">线2上的一点</param>
        /// <param name="v2">线2的方向向量</param>
        /// <param name="intersection">返回的交点</param>
        /// <returns>返回结果，true 有交点，false 无交点</returns>
        public static bool FindLineIntersection(
                                                    Vector3 a1, Vector3 v1, // 直线L₁的点和方向向量
                                                    Vector3 a2, Vector3 v2, // 直线L₂的点和方向向量
                                                    out Vector3 intersection)
        {
            intersection = default;

            Vector3 delta = a2 - a1;
            // 判断是否共面（混合积是否为0）
            Vector3 cross = Vector3.Cross(v1, v2);
            double mixedProduct = Vector3.Dot(cross, delta);
            //if (Math.Abs(mixedProduct) > epsilon) return false;

            
            // 构造前两个方程的系数矩阵
            float[,] A = {
                            { v1.X, -v2.X },
                            { v1.Y, -v2.Y }
                        };

            float[] B = {
                            a2.X - a1.X,
                            a2.Y - a1.Y
                        };

            // 计算行列式
            float det = A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0];
            if (Math.Abs(det) < 1e-6) // 行列式接近零，可能平行或重合
                return false;

            // 克莱姆法则求解t和s
            float t = (A[1, 1] * B[0] - A[0, 1] * B[1]) / det;
            float s = (A[0, 0] * B[1] - A[1, 0] * B[0]) / det;

            // 验证第三个分量
            float z1 = a1.Z + t * v1.Z;
            float z2 = a2.Z + s * v2.Z;
            if (Math.Abs(z1 - z2) > 1e-6)
                return false; // 异面直线

            intersection = a1 + v1 * t;
            return true;

        }

        public static bool ArePointsCoplanar(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
        {
            Vector3 ab = b - a;
            Vector3 ac = c - a;
            Vector3 ad = d - a;

            // 计算叉乘 (AB × AC)
            Vector3 cross = Vector3.Cross(ab, ac);

            // 计算混合积 (AB × AC) · AD 
            double volume = Vector3.Dot(cross, ad);

            // 判断是否接近零（考虑浮点误差）
            const double epsilon = 1e-6;
            return Math.Abs(volume) < epsilon;
        }


    }



    public struct Vector3
    {
        public float X { get; }
        public float Y { get; }
        public float Z { get; }

        public Vector3(float x, float y, float z)
        {
            X = x;
            Y = y;
            Z = z;
        }
        public Vector3(double x, double y, double z)
        {
            X = (float)x;
            Y = (float)y;
            Z = (float)z;
        }

        // 向量加法
        public static Vector3 operator +(Vector3 a, Vector3 b) =>
            new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);

        // 向量减法
        public static Vector3 operator -(Vector3 a, Vector3 b) =>
            new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);

        // 标量乘法
        public static Vector3 operator *(Vector3 v, float scalar) =>
            new Vector3(v.X * scalar, v.Y * scalar, v.Z * scalar);

        // 向量叉积计算 
        public static Vector3 Cross(Vector3 a, Vector3 b)
        {
            return new Vector3(
                a.Y * b.Z - a.Z * b.Y,
                a.Z * b.X - a.X * b.Z,
                a.X * b.Y - a.Y * b.X
            );
        }
        public static double Dot(Vector3 a, Vector3 b) => a.X * b.X + a.Y * b.Y + a.Z * b.Z;


    }

}
